package crypto.key;

import java.security.Provider;
import java.security.Provider.Service;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Set;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

public enum EncryptUtils {

    /**
     * 单例
     */
    SINGLETON;

    private static final String SECRECT = "passwrod";

    public String wrap(String keyString) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器，指定密钥长度为128，指定随机源的种子为指定的密钥(这里是"passward")
        keyGenerator.init(128, new SecureRandom(SECRECT.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.WRAP_MODE, secretKeySpec);
        SecretKeySpec key = new SecretKeySpec(keyString.getBytes(), "AES");
        byte[] bytes = cipher.wrap(key);
        return Hex.encodeHexString(bytes);
    }

    public String unwrap(String keyString) throws Exception {
        byte[] rawKey = Hex.decodeHex(keyString);
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器，指定密钥长度为128，指定随机源的种子为指定的密钥(这里是"passward")
        keyGenerator.init(128, new SecureRandom(SECRECT.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.UNWRAP_MODE, secretKeySpec);
        SecretKey key = (SecretKey) cipher.unwrap(rawKey, "AES", Cipher.SECRET_KEY);
        return new String(key.getEncoded());
    }

    public static void main(String[] args) throws Exception {
        printProviders();
        System.out.println("----");
        System.out.println(encryptByAes("123456", "12345678"));
        System.out.println("=======");
        String wrapKey = EncryptUtils.SINGLETON.wrap("doge");
        System.out.println(wrapKey);
        System.out.println(EncryptUtils.SINGLETON.unwrap(wrapKey));
    }

    public static String encryptByAes(String content, String password) throws Exception {
        //这里指定了算法为AES_128，工作模式为EBC，填充模式为NoPadding
        Cipher cipher = Cipher.getInstance("AES");
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //因为AES要求密钥的长度为128，我们需要固定的密码，因此随机源的种子需要设置为我们的密码数组
        keyGenerator.init(128, new SecureRandom(password.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
        //基于加密模式和密钥初始化Cipher
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        //单部分加密结束，重置Cipher
        byte[] bytes = cipher.doFinal(content.getBytes());
        //加密后的密文由二进制序列转化为十六进制序列，依赖apache-codec包
        return Hex.encodeHexString(bytes);
    }

    public static void printProviders() {
        Provider[] providers = Security.getProviders();
        if (null != providers) {
            for (Provider provider : providers) {
                Set<Service> services = provider.getServices();
                for (Provider.Service service : services) {
                    if ("Cipher".equals(service.getType())) {
                        System.out.println(String.format("provider:%s,type:%s,algorithm:%s", service.getProvider(), service.getType(), service.getAlgorithm()));
                    }
                }
            }
        }
    }
}
